package com.ruoyi.cost.controller;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.cost.domain.AccAmount;
import com.ruoyi.cost.domain.AccSubject;
import com.ruoyi.cost.domain.SubTree;
import com.ruoyi.cost.service.IAccAmountService;
import com.ruoyi.cost.service.IAccSubjectService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.cost.domain.AccVou;
import com.ruoyi.cost.service.IAccVouService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 记账凭证Controller
 *
 * @author 王志旸
 * @date 2024-07-09
 */
@RestController
@RequestMapping("/cost/vou")
public class AccVouController extends BaseController {

    @Autowired
    private IAccVouService accVouService;
    @Autowired
    private IAccAmountService accAmountService;

    /**
     * 查询记账凭证列表
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:list')")
    @GetMapping("/list")
    public TableDataInfo list(AccVou accVou) {
        startPage();
        List<AccVou> list = accVouService.selectAccVouList(accVou);
        for (AccVou vou : list) {
            String accVouCode = vou.getAccVouCode();
            String accVouDate = vou.getAccVouDate();
            Double yusuan = 0.0;
            Double caiwu = 0.0;
            List<AccVou> list1 = accVouService.findByAccVouCodeAndAccVouDate(accVouCode, accVouDate);
            for (AccVou accVou1 : list1) {
                String subCode = accVou1.getSubCode();
                AccSubject accSubject = accVouService.getVouSubType(subCode);
                String accSubType = accSubject.getAccSubType();
                ArrayList<String> objects = new ArrayList<>();
                objects.add("预算结余类");
                objects.add("预算收入类");
                objects.add("预算支出类");
                if (objects.contains(accSubType)) {
                    yusuan += Double.parseDouble(accVou1.getCreditLocalCurr());
                } else {
                    caiwu += Double.parseDouble(accVou1.getCreditLocalCurr());
                }
            }
            vou.setCreditLocalCurr(caiwu.toString());
            vou.setCreditOriginalCurr(yusuan.toString());
            vou.setCreditLocalCurr(String.format("%.2f", Double.parseDouble(vou.getCreditLocalCurr())));
            vou.setDebtorLocalCurr(String.format("%.2f", Double.parseDouble(vou.getDebtorLocalCurr())));
            vou.setAccVouCode(vou.getAccVouCode());
        }
        return getDataTable(list);
    }

    //    @PreAuthorize("@ss.hasPermi('cost:vou:list')")
    @GetMapping("/getSupListBySub")
    public AjaxResult getSupListBySub(String accMode, String accSubName) {
        List<Map> supCategorys = accVouService.getSupCategory(accMode, accSubName);
        List<Map> maps = new ArrayList<>();
        for (Map supCategory : supCategorys) {
            HashMap map = new HashMap<>();
            map.put("id", supCategory.get("custom_name"));
            map.put("value", supCategory.get("custom_name"));
            map.put("label", supCategory.get("custom_name"));
            maps.add(map);
        }
        return success(maps);
    }

    /**
     * 查询单个凭证科目
     *
     * @return
     * @throws Exception
     */
//    @PreAuthorize("@ss.hasPermi('cost:amount:list')")
    @GetMapping("/getListCaiWu")
    public TableDataInfo getListCaiWu(AccVou accVou) throws Exception {
        List<AccVou> accVous = accVouService.getList(accVou);
        List<AccVou> accVous1 = new ArrayList<>();
        for (AccVou vous : accVous) {
            String subCode = vous.getSubCode();
            String substring = subCode.substring(0, 1);
            if (Integer.parseInt(substring) < 6) {
                accVous1.add(vous);
            }
        }
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        for (AccVou vous : accVous1) {
            Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
            vous.setAccVouDate(outputDateFormat.format(accVouDate));
        }
        return getDataTable(accVous1);
    }

    @GetMapping("/getList")
    public TableDataInfo getList(AccVou accVou) throws Exception {
        List<AccVou> accVous = accVouService.getList(accVou);
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        for (AccVou vous : accVous) {
            Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
            vous.setAccVouDate(outputDateFormat.format(accVouDate));
        }
        return getDataTable(accVous);
    }

    @GetMapping("/getListyusuan")
    public TableDataInfo getListyusuan(AccVou accVou) throws Exception {
        List<AccVou> accVous = accVouService.getList(accVou);
        List<AccVou> accVous1 = new ArrayList<>();
        for (AccVou vous : accVous) {
            String subCode = vous.getSubCode();
            String substring = subCode.substring(0, 1);
            if (Integer.parseInt(substring) >= 6) {
                accVous1.add(vous);
            }
        }
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        for (AccVou vous : accVous) {
            Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
            vous.setAccVouDate(outputDateFormat.format(accVouDate));
        }
        return getDataTable(accVous1);
    }

    //    @PreAuthorize("@ss.hasPermi('cost:amount:list')")
    @GetMapping("/getSupList")
    public TableDataInfo getSupList(String ids) throws Exception {
        String[] split = ids.split(",");
        List list = new ArrayList<>();
        for (String s : split) {


            List<Map> mapList = new ArrayList<>();
            AccVou byId = accVouService.selectAccVouById(s);
            String spare1 = byId.getSpare1();
            String spare2 = byId.getSpare2();
            String spare3 = byId.getSpare3();
            String spare4 = byId.getSpare4();
            String spare5 = byId.getSpare5();
            String spare6 = byId.getSpare6();
            String spare7 = byId.getSpare7();
            String spare8 = byId.getSpare8();
            String spare9 = byId.getSpare9();
            String spare10 = byId.getSpare10();
            String spare11 = byId.getSpare11();
            String spare12 = byId.getSpare12();
            String spare13 = byId.getSpare13();
            String spare14 = byId.getSpare14();
            String spare15 = byId.getSpare15();
            String spare16 = byId.getSpare16();
            String spare17 = byId.getSpare17();
            String spare18 = byId.getSpare18();
            String spare19 = byId.getSpare19();
            String spare20 = byId.getSpare20();
            String spare21 = byId.getSpare21();
            String spare22 = byId.getSpare22();
            String spare23 = byId.getSpare23();
            String spare24 = byId.getSpare24();
            String spare25 = byId.getSpare25();
            String spare26 = byId.getSpare26();
            String spare27 = byId.getSpare27();
            String spare28 = byId.getSpare28();
            String spare29 = byId.getSpare29();
            String spare30 = byId.getSpare30();
            ArrayList<String> spares = new ArrayList<>();
            spares.add(spare1);
            spares.add(spare2);
            spares.add(spare3);
            spares.add(spare4);
            spares.add(spare5);
            spares.add(spare6);
            spares.add(spare7);
            spares.add(spare8);
            spares.add(spare9);
            spares.add(spare10);
            spares.add(spare11);
            spares.add(spare12);
            spares.add(spare13);
            spares.add(spare14);
            spares.add(spare15);
            spares.add(spare16);
            spares.add(spare17);
            spares.add(spare18);
            spares.add(spare19);
            spares.add(spare20);
            spares.add(spare21);
            spares.add(spare22);
            spares.add(spare23);
            spares.add(spare24);
            spares.add(spare25);
            spares.add(spare26);
            spares.add(spare27);
            spares.add(spare28);
            spares.add(spare29);
            spares.add(spare30);

            List<Map> list1 = accVouService.getSupListBySpares(spares);
            LinkedHashMap<Object, Object> objectObjectHashMap = new LinkedHashMap<>();
            AccSubject vouSubType = accVouService.getVouSubType(byId.getSubCode());
            objectObjectHashMap.put("会计科目", byId.getSubCode() + " " + vouSubType.getAccSubName());
            for (Map map : list1) {
                Object custom_name1 = map.get("custom_name1");
                String custom_name2 = (String) map.get("custom_name2");
                String custom_code = (String) map.get("custom_code");
                objectObjectHashMap.put(custom_name1, custom_code + " " + custom_name2);
            }
            objectObjectHashMap.put("金额", Double.parseDouble(byId.getCreditLocalCurr()) + Double.parseDouble(byId.getDebtorLocalCurr()));
            list.add(objectObjectHashMap);
        }
        return getDataTable(list);
    }

    @Autowired
    private IAccSubjectService accSubjectService;

    //    @PreAuthorize("@ss.hasPermi('cost:amount:list')")
    @GetMapping("/list1")
    public TableDataInfo list1(String accMode, String accSubName) throws Exception {
        List<AccVou> list = accVouService.selectVouList(accMode, accSubName);
        AccSubject one = accSubjectService.getOneBalanceDirection(accSubName);
        String balanceDirection = one.getBalanceDirection();
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        AccAmount accAmount2 = accAmountService.getBeginCurr1(accMode, accSubName);
        AccVou accVou1 = new AccVou();
        if (accAmount2 != null) {
            accVou1.setAccVouDate(accAmount2.getAccYear() + "-01-31");
            accVou1.setAccPeriod(accAmount2.getStartLocalCurr());
            accVou1.setAccVouRemark("期初余额");
            accVou1.setEndBalance(balanceDirection);
            accVou1.setId(UUID.randomUUID().toString());
        }
        Double start = 0.0;
        if (accAmount2 != null) {
            if (accAmount2.getStartLocalCurr().equals("")) {
                accAmount2.setStartLocalCurr("0");
            }
            start = Double.parseDouble(accAmount2.getStartLocalCurr());
        }
        Map<String, AccVou> monthlySummaryMap = new LinkedHashMap<>();
        ArrayList<AccVou> accVous = new ArrayList<>();
        accVous.add(accVou1);
        Double startyearC = 0.0;
        Double startD = 0.0;

        for (int i = 0; i < list.size(); i++) {
            AccVou accVou = list.get(i);
            Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
            String monthKey = monthFormat.format(accVouDate);

            // 统计每个月的数据
            monthlySummaryMap.putIfAbsent(monthKey, new AccVou());
            AccVou summary = monthlySummaryMap.get(monthKey);

            // 累加当月的金额
            summary.setDebtorLocalCurr(sum(summary.getDebtorLocalCurr(), accVou.getDebtorLocalCurr()));
            summary.setCreditLocalCurr(sum(summary.getCreditLocalCurr(), accVou.getCreditLocalCurr()));
            startyearC = startyearC + Double.parseDouble(accVou.getCreditLocalCurr());
            startD = startD + Double.parseDouble(accVou.getDebtorLocalCurr());
            // 将当前记录的日期格式转换
            accVou.setAccVouDate(outputDateFormat.format(accVouDate));

            Double d = Double.parseDouble(accVou.getCreditLocalCurr());
            Double j = Double.parseDouble(accVou.getDebtorLocalCurr());
            if (balanceDirection.equals("借")) {
                start = start + j - d;
            } else {
                start = start - j + d;
            }
            accVou.setAccPeriod(String.format("%.2f", start));
            if (start == 0.0) {
                accVou.setEndBalance("平");
            }
            accVou.setEndBalance(balanceDirection);
            // 检查是否为当前月的最后一条记录
            boolean isLastOfMonth = i == list.size() - 1 ||
                    !monthFormat.format(inputDateFormat.parse(list.get(i + 1).getAccVouDate())).equals(monthKey);
            accVous.add(accVou);

            if (isLastOfMonth) {
                AccVou monthlySummary = new AccVou();
                AccVou yearSummary = new AccVou();
                monthlySummary.setAccVouRemark("本期合计");
                monthlySummary.setAccPeriod(String.format("%.2f", start));
                monthlySummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));
                monthlySummary.setDebtorLocalCurr(String.format("%.2f", Double.parseDouble(summary.getDebtorLocalCurr())));
                monthlySummary.setCreditLocalCurr(String.format("%.2f", Double.parseDouble(summary.getCreditLocalCurr())));
                accVou.setEndBalance(balanceDirection);
                yearSummary.setAccVouRemark("本年合计");
                yearSummary.setAccPeriod(String.format("%.2f", start));
                yearSummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));
                yearSummary.setDebtorLocalCurr(String.format("%.2f", startD));
                yearSummary.setCreditLocalCurr(String.format("%.2f", startyearC));
                accVou.setEndBalance(balanceDirection);
                if (start == 0.0) {
                    accVou.setEndBalance("平");
                }
                accVous.add(monthlySummary);
                accVous.add(yearSummary);
            }
        }
        return getDataTable(accVous);
    }

    @GetMapping("/vouListSup0")
    public TableDataInfo vouListSup0(String accMode, String accSubName, String accBusiness) throws Exception {
        if (accSubName == null) {
            return null;
        }
        List<AccVou> list = accVouService.selectVouList(accMode,accSubName);
        String[] supList = accBusiness.split(",");
        List<HashMap> map = accVouService.findSupsBySub(supList, accMode,accSubName);
        ArrayList<AccVou> accVous = new ArrayList<>();
        for (AccVou accVou : list) {
            Boolean flag = true;
            for (HashMap hashMap : map) {
                String assisted_code = (String) hashMap.get("assisted_code");
                Field field = AccVou.class.getDeclaredField("spare" + assisted_code);
                field.setAccessible(true); // 允许访问私有字段
                String spareValue = (String) field.get(accVou);
                if (spareValue == null || spareValue.equals("")){
                    flag = false;
                }
            }
            if (flag){
                accVous.add(accVou);
            }
        }
        List<Map<String, Object>> maps = vouListSup1(accMode, accSubName, supList[0], accVous);

        if (maps == null || maps.size() == 0) {
            return null;
        }
        for (Map<String, Object> vou : maps) {
            for (HashMap hashMap : map) {
                String assisted_code = (String) hashMap.get("assisted_code");
                String assisted_name = (String) hashMap.get("assisted_name");
                String spare = (String) vou.get("spare"+assisted_code);
                Map spareValue = accVouService.findSpareValue(spare,assisted_name,accMode);

                try {
                    vou.put(assisted_name, spareValue.get("custom_name"));
                } catch (Exception e) {
                    System.out.println(spare);
                }
            }
            if (vou.get("subCode") != null && vou.get("accSubName") != null) {
                vou.put("subCode",(String)vou.get("subCode")+vou.get("accSubName"));
            }
        }

        return getDataTable(maps);
    }

    @GetMapping("/vouListSup1")
    public List<Map<String,Object>> vouListSup1(String accMode, String accSubName, String accBusiness,List<AccVou> list) throws Exception {
//        List<AccVou> list = accVouService.selectVouList(accMode, accSubName);
        AccSubject one = accSubjectService.getOneBalanceDirection(accSubName);
        String balanceDirection = one.getBalanceDirection();
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        AccAmount accAmount2 = accAmountService.getBeginCurr1(accMode, accSubName);
        String[] split = accBusiness.split(",");
        HashSet<String> stringHashSet = new HashSet<>();
        AccVou accVou1 = new AccVou();

        Map<String, AccVou> monthlySummaryMap = new LinkedHashMap<>();
        ArrayList<AccVou> accVous = new ArrayList<>();
        accVous.add(accVou1);
        Double startyearC = 0.0;
        Double startD = 0.0;
        Double zongyue = 0.0;
        for (String business : split) {
            Map<String, String> spare = getSpare(accSubName, business, accMode);
            String spare1 = spare.get("spare");
            if (spare1 == null) {
                return null;
            }
            String allYuE = accVouService.getAllYuE(accMode, accSubName, business, spare1);
            if (allYuE == null) {
                allYuE = "0";
            }
            zongyue = Double.parseDouble(String.format("%.2f", Double.parseDouble(allYuE)));

           if (accAmount2 != null) {
                accVou1.setAccVouDate(accAmount2.getAccYear() + "-01-01");
                accVou1.setAccPeriod(String.format("%.2f", zongyue));
                accVou1.setAccVouRemark("期初余额");
                accVou1.setEndBalance(balanceDirection);
                accVou1.setId(UUID.randomUUID().toString());
            }


            for (int i = 0; i < list.size(); i++) {
                AccVou accVou = list.get(i);
                // 统计每个月的数据
                Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
                String monthKey = monthFormat.format(accVouDate);
                monthlySummaryMap.putIfAbsent(monthKey, new AccVou());
                AccVou summary = monthlySummaryMap.get(monthKey);
                Map<String, String> map = getSpares(accVou.getSubCode(), business, accVou.getId(), accMode);
                accVou.setSupMap(map.get("supName"));
                // 检查是否为当前月的最后一条记录
                boolean isLastOfMonth = i == list.size() - 1 ||
                        !monthFormat.format(inputDateFormat.parse(list.get(i + 1).getAccVouDate())).equals(monthKey);

//                accVou.setSubCode(accVou.getSubCode() + " " + accVou.getAccSubName());
//            accVous.add(accVou);
                if (accBusiness != null && !accBusiness.equals("") && accVou.getSupMap() != null && !accVou.getSupMap().equals("")) {
                    // 累加当月的金额
                    summary.setDebtorLocalCurr(sum(summary.getDebtorLocalCurr(), accVou.getDebtorLocalCurr()));
                    summary.setCreditLocalCurr(sum(summary.getCreditLocalCurr(), accVou.getCreditLocalCurr()));
                    startyearC = startyearC + Double.parseDouble(accVou.getCreditLocalCurr());
                    startD = startD + Double.parseDouble(accVou.getDebtorLocalCurr());
                    // 将当前记录的日期格式转换
                    accVou.setAccVouDate(outputDateFormat.format(accVouDate));
                    Double d = Double.parseDouble(accVou.getCreditLocalCurr());
                    Double j = Double.parseDouble(accVou.getDebtorLocalCurr());

                    accVou.setEndBalance(balanceDirection);
                    if (balanceDirection.equals("借")) {
                        zongyue = zongyue + j - d;
                    } else {
                        zongyue = zongyue - j + d;
                    }
                    accVou.setAccPeriod(String.format("%.2f", zongyue));
                    if (zongyue == 0.0) {
                        accVou.setEndBalance("平");
                    }
                    accVous.add(accVou);
                }
                if (isLastOfMonth) {
                    AccVou monthlySummary = new AccVou();
                    AccVou yearSummary = new AccVou();
                    monthlySummary.setAccVouRemark("本期合计");
                    monthlySummary.setAccPeriod(String.format("%.2f", zongyue));
                    monthlySummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));
                    accVou.setEndBalance(balanceDirection);
                    yearSummary.setAccVouRemark("本年合计");
                    yearSummary.setAccPeriod(String.format("%.2f", zongyue));
                    yearSummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));
                    yearSummary.setDebtorLocalCurr(String.format("%.2f", startD));
                    yearSummary.setCreditLocalCurr(String.format("%.2f", startyearC));
                    accVou.setEndBalance(balanceDirection);
                    if (zongyue == 0.0) {
                        accVou.setEndBalance("平");
                    }
                    if (accBusiness != null && !accBusiness.equals("") && accVou.getSupMap() != null && !accVou.getSupMap().equals("")) {
                        yearSummary.setDebtorLocalCurr(String.format("%.2f", startD));
                        yearSummary.setCreditLocalCurr(String.format("%.2f", startyearC));
                        monthlySummary.setDebtorLocalCurr(String.format("%.2f", Double.parseDouble(summary.getDebtorLocalCurr())));
                        monthlySummary.setCreditLocalCurr(String.format("%.2f", Double.parseDouble(summary.getCreditLocalCurr())));
//                    accVous.add(accVou);
                        accVous.add(monthlySummary);
                        accVous.add(yearSummary);
                    }
                }
            }
        }
        if (accVous.size() == 1) {
            return null;
        }


        List<Map<String, Object>> listOfMaps = new ArrayList<>();

        for (AccVou accVou : accVous) {
            Map<String, Object> map = new HashMap<>();
            // 使用反射获取所有字段
            Field[] fields = accVou.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true); // 设置私有字段也可以访问
                try {
                    map.put(field.getName(), field.get(accVou)); // 将字段名和对应的值放入 map
                } catch (IllegalAccessException e) {
                    e.printStackTrace(); // 处理异常
                }
            }
            listOfMaps.add(map);
        }
        return listOfMaps;
    }

    public Map<String, String> getSpare(String accSubNum, String accBusiness, String accMode) {
        Map subAssistedAcc = accAmountService.getSubAssistedAcc(accSubNum, accBusiness, accMode);
        HashMap<String, String> map = new HashMap<>();
        if (subAssistedAcc != null) {
            String assisted_code = subAssistedAcc.get("assisted_code").toString();
            String spare = "spare";
            spare = spare + assisted_code;
            map.put("spare", spare);
            return map;
        }
        return new HashMap<>();
    }

    @GetMapping("/vouListSup3")
    public TableDataInfo vouListSup3(String accMode, String accSubName, String accBusiness, String accBusiness1) throws Exception {
        List<AccVou> list = accVouService.selectVouList1(accMode);
        String[] supList = accBusiness.split(",");
        String[] supSupList = accBusiness1.split(",");
        HashSet<String> stringHashSet = new HashSet<>();
        ArrayList<String> codeList = new ArrayList<>();
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        List<HashMap> map = null;
        List<HashMap> map1 = null;
        if (supSupList.length> 0) {
             map = accVouService.findSupsOne(supList, accMode);
             map1 = accVouService.findSupsLocOne(supList, accMode, supSupList);
        } else if (supSupList.length == 0) {
            return null;
        }else {
            map = accVouService.findSups(supList, accMode);
            map1 = accVouService.findSupsLoc(supList, accMode, supSupList);
        }

        for (HashMap hashMap : map) {
            stringHashSet.add((String) hashMap.get("subject_code"));
            codeList.add((String) hashMap.get("assisted_code"));
            String assisted_name = (String) hashMap.get("assisted_name");
            String assisted_code = (String) hashMap.get("assisted_code");
            objectObjectHashMap.put(assisted_name, assisted_code);
        }
        List<AccVou> vouList = list.stream()
                .filter(obj -> stringHashSet.contains(obj.getSubCode()))
                .collect(Collectors.toList());
        for (HashMap hashMap : map) {
            String assisted_name = (String) hashMap.get("assisted_name");
            for (HashMap hashMap1 : map1) {
                String custom_name = (String) hashMap1.get("custom_name");
                if (assisted_name.equals(custom_name)) {
                    hashMap.put("code", (String) hashMap1.get("name"));
                }
            }
        }
        List<AccVou> matchedList = new ArrayList<>();
        for (AccVou accVou : vouList) {
            boolean allMatch = true; // 初始化为true，表示当前对象假定所有条件匹配
            for (HashMap<String, Object> hashMap : map) {
                String assisted_name = (String) hashMap.get("assisted_name");
                String assisted_code = (String) hashMap.get("assisted_code");

                Field field = AccVou.class.getDeclaredField("spare" + assisted_code);
                field.setAccessible(true); // 允许访问私有字段
                String spareValue = (String) field.get(accVou);

                if (!spareValue.equals(hashMap.get("code"))) {
                    allMatch = false; // 有一个不匹配则标志置为false
                    break; // 退出当前内层循环
                }
            }

            if (allMatch) {
                matchedList.add(accVou); // 如果所有条件都匹配，将该对象添加到新的列表中
            }
        }
        List list1 = vouListSup2(accMode, matchedList, null, supList[0], supSupList[0]);
        if (list1 == null) {
            return null;
        }
        return getDataTable(list1);
    }

    @GetMapping("/vouListSup2")
    public List vouListSup2(String accMode, List<AccVou> list, String accSubName, String accBusiness, String accBusiness1) throws Exception {
//        List<AccVou> list = accVouService.selectVouList1(accMode);
        List<AccVou> list1 = new ArrayList<>();
        SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> list2 = new ArrayList<>();
        for (AccVou accVou : list) {
            Map<String, String> spares = getSpares(accVou.getSubCode(), accBusiness, accVou.getId(), accMode);
            accVou.setSupMap(spares.get("supName"));
            accVou.setSpare(spares.get("spare"));
            if (accBusiness != null && !accBusiness.equals("") && accVou.getSupMap() != null && !accVou.getSupMap().equals("")) {
                if (accBusiness1.equals(accVou.getSupMap())) {
                    list1.add(accVou);
                    if (accVou.getSpare().equals("spare1")) {
                        list2.add(accVou.getSpare1());
                    } else if (accVou.getSpare().equals("spare2")) {
                        list2.add(accVou.getSpare2());
                    } else if (accVou.getSpare().equals("spare3")) {
                        list2.add(accVou.getSpare3());
                    } else if (accVou.getSpare().equals("spare4")) {
                        list2.add(accVou.getSpare4());
                    } else if (accVou.getSpare().equals("spare5")) {
                        list2.add(accVou.getSpare5());
                    } else if (accVou.getSpare().equals("spare6")) {
                        list2.add(accVou.getSpare6());
                    } else if (accVou.getSpare().equals("spare7")) {
                        list2.add(accVou.getSpare7());
                    } else if (accVou.getSpare().equals("spare8")) {
                        list2.add(accVou.getSpare8());
                    } else if (accVou.getSpare().equals("spare9")) {
                        list2.add(accVou.getSpare9());
                    } else if (accVou.getSpare().equals("spare10")) {
                        list2.add(accVou.getSpare10());
                    } else if (accVou.getSpare().equals("spare11")) {
                        list2.add(accVou.getSpare11());
                    } else if (accVou.getSpare().equals("spare12")) {
                        list2.add(accVou.getSpare12());
                    } else if (accVou.getSpare().equals("spare13")) {
                        list2.add(accVou.getSpare13());
                    } else if (accVou.getSpare().equals("spare14")) {
                        list2.add(accVou.getSpare14());
                    } else if (accVou.getSpare().equals("spare15")) {
                        list2.add(accVou.getSpare15());
                    } else if (accVou.getSpare().equals("spare16")) {
                        list2.add(accVou.getSpare16());
                    } else if (accVou.getSpare().equals("spare17")) {
                        list2.add(accVou.getSpare17());
                    } else if (accVou.getSpare().equals("spare18")) {
                        list2.add(accVou.getSpare18());
                    } else if (accVou.getSpare().equals("spare19")) {
                        list2.add(accVou.getSpare19());
                    } else if (accVou.getSpare().equals("spare20")) {
                        list2.add(accVou.getSpare20());
                    } else if (accVou.getSpare().equals("spare21")) {
                        list2.add(accVou.getSpare21());
                    } else if (accVou.getSpare().equals("spare22")) {
                        list2.add(accVou.getSpare22());
                    } else if (accVou.getSpare().equals("spare23")) {
                        list2.add(accVou.getSpare23());
                    } else if (accVou.getSpare().equals("spare24")) {
                        list2.add(accVou.getSpare24());
                    } else if (accVou.getSpare().equals("spare25")) {
                        list2.add(accVou.getSpare25());
                    } else if (accVou.getSpare().equals("spare27")) {
                        list2.add(accVou.getSpare26());
                    } else if (accVou.getSpare().equals("spare27")) {
                        list2.add(accVou.getSpare27());
                    } else if (accVou.getSpare().equals("spare28")) {
                        list2.add(accVou.getSpare28());
                    } else if (accVou.getSpare().equals("spare29")) {
                        list2.add(accVou.getSpare29());
                    } else if (accVou.getSpare().equals("spare30")) {
                        list2.add(accVou.getSpare30());
                    }
                }
            }
        }
        HashSet<String> objects = new HashSet<>();
        HashMap<String, String> map1 = new HashMap<>();
        if (accSubName == null || accSubName.equals("")) {
            for (AccVou accVou : list1) {
                String subCode = accVou.getSubCode();
                objects.add(subCode);
                map1.put(subCode, accVou.getSpare());
            }
        }
        List<AccAmount> beginCList = new ArrayList();
        for (String subCode : objects) {

            String spare = map1.get(subCode);

            List<AccAmount> beginCurr2 = accAmountService.getBeginCurr2(accMode, subCode, spare, list2);
            beginCList.addAll(beginCurr2);
        }
        AccVou accVou1 = new AccVou();
//        if (accAmount2 != null) {
        if (list1.size() == 0) {
            return null;
        }
        AccVou accVou2 = list1.get(0);
        accVou1.setAccVouDate(accVou2.getAccYear() + "-01-01");
//            accVou1.setAccPeriod(accAmount2.getStartLocalCurr());
        accVou1.setAccVouRemark("期初余额");
//            AccSubject one1 = accSubjectService.getOneBalanceDirection(accVou1.getSubCode());
//            String balanceDirection1 = one1.getBalanceDirection();
//            accVou1.setEndBalance(balanceDirection1);
        accVou1.setId(UUID.randomUUID().toString());
//        }
        Double start = 0.0;
//        if (accAmount2 != null) {
//            start = Double.parseDouble(accAmount2.getStartLocalCurr());
//        }
        for (AccAmount accAmount : beginCList) {
            start += Double.parseDouble(accAmount.getStartLocalCurr());
        }
        Map<String, AccVou> monthlySummaryMap = new LinkedHashMap<>();
        ArrayList<AccVou> accVous = new ArrayList<>();
        accVou1.setAccPeriod(String.format("%.2f", start));
        accVous.add(accVou1);
        Double startyearC = 0.0;
        Double startD = 0.0;
        for (int i = 0; i < list1.size(); i++) {
            AccVou accVou = list1.get(i);
            Date accVouDate = inputDateFormat.parse(accVou.getAccVouDate());
            String monthKey = monthFormat.format(accVouDate);
            AccSubject one = accSubjectService.getOneBalanceDirection(accVou.getSubCode());
            String balanceDirection = one.getBalanceDirection();
            // 统计每个月的数据
            monthlySummaryMap.putIfAbsent(monthKey, new AccVou());
            AccVou summary = monthlySummaryMap.get(monthKey);

            // 累加当月的金额

            // 将当前记录的日期格式转换
            accVou.setAccVouDate(outputDateFormat.format(accVouDate));

            Double d = Double.parseDouble(accVou.getCreditLocalCurr());
            Double j = Double.parseDouble(accVou.getDebtorLocalCurr());
            if (balanceDirection.equals("借")) {
                start = start + j - d;
            } else {
                start = start - j + d;
            }
            accVou.setAccPeriod(String.format("%.2f", start));
            if (start == 0.0) {
                accVou.setEndBalance("平");
            }
            accVou.setEndBalance(balanceDirection);
            // 检查是否为当前月的最后一条记录
            boolean isLastOfMonth = i == list1.size() - 1 ||
                    !monthFormat.format(inputDateFormat.parse(list1.get(i + 1).getAccVouDate())).equals(monthKey);

//            accVou.setSupMap(getSpares(accVou.getSubCode(), accBusiness, accVou.getId(), accMode).get("supName"));

                    summary.setDebtorLocalCurr(sum(summary.getDebtorLocalCurr(), accVou.getDebtorLocalCurr()));
                    summary.setCreditLocalCurr(sum(summary.getCreditLocalCurr(), accVou.getCreditLocalCurr()));
                    startyearC = startyearC + Double.parseDouble(accVou.getCreditLocalCurr());
                    startD = startD + Double.parseDouble(accVou.getDebtorLocalCurr());
                    accVous.add(accVou);


            if (isLastOfMonth) {
                AccVou monthlySummary = new AccVou();
                AccVou yearSummary = new AccVou();
                monthlySummary.setAccVouRemark("本期合计");
                monthlySummary.setAccPeriod(String.format("%.2f", start));
                monthlySummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));

                accVou.setEndBalance(balanceDirection);
                yearSummary.setAccVouRemark("本年合计");
                yearSummary.setAccPeriod(String.format("%.2f", start));
                yearSummary.setAccVouDate(outputDateFormat.format(getLastDayOfMonth(accVouDate)));

                accVou.setEndBalance(balanceDirection);
                if (start == 0.0) {
                    accVou.setEndBalance("平");
                }

                if (monthlySummary != null && summary != null) {
                    String debtorLocalCurrStr = summary.getDebtorLocalCurr();
                    String creditLocalCurrStr = summary.getCreditLocalCurr();
                    if (debtorLocalCurrStr != null && !debtorLocalCurrStr.isEmpty()) {
                        double debtorLocalCurr = Double.parseDouble(debtorLocalCurrStr);
                        monthlySummary.setDebtorLocalCurr(String.format("%.2f", debtorLocalCurr));
                    }
                    if (creditLocalCurrStr != null && !creditLocalCurrStr.isEmpty()) {
                        double creditLocalCurr = Double.parseDouble(creditLocalCurrStr);
                        monthlySummary.setCreditLocalCurr(String.format("%.2f", creditLocalCurr));
                    }

                }

                if (yearSummary != null && startD != null && startyearC != null) {
                    yearSummary.setDebtorLocalCurr(String.format("%.2f", startD));
                    yearSummary.setCreditLocalCurr(String.format("%.2f", startyearC));
                }
                        accVous.add(monthlySummary);
                        accVous.add(yearSummary);

            }
        }
        if (accVous.size() == 1) {
            return null;
        }
        return accVous;
    }

    public Map<String, String> getSpares(String accSubNum, String accBusiness, String id, String accMode) {
        Map subAssistedAcc = accAmountService.getSubAssistedAcc(accSubNum, accBusiness, accMode);
        HashMap<String, String> map = new HashMap<>();
        if (subAssistedAcc != null) {
            String assisted_code = subAssistedAcc.get("assisted_code").toString();
            String spare = "spare";
            spare = spare + assisted_code;
            String supName = accAmountService.getVouSupSpares(accSubNum, accBusiness, id, accMode, spare);
            map.put("spare", spare);
            map.put("supName", supName);
            return map;
        }
        return new HashMap<>();
    }


    private String sum(String val1, String val2) {
        double result = 0.0;
        if (val1 != null && !val1.isEmpty()) {
            result += Double.parseDouble(val1);
        }
        if (val2 != null && !val2.isEmpty()) {
            result += Double.parseDouble(val2);
        }
        return String.valueOf(result);
    }


    // 获取某个日期对应月的最后一天
    private Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    @GetMapping("/initSup")
    public AjaxResult initSup(String accMode) {
        List<Map<String, String>> parent = accVouService.findSupParent(accMode);
        List<SubTree> list = new ArrayList<>();
        for (Map<String, String> map : parent) {
            List<Map<String, String>> child = accVouService.findSupChild(accMode, map.get("custom_code"));
            SubTree subTree = new SubTree();
            subTree.setValue(map.get("custom_name"));
            subTree.setLabel(map.get("custom_name"));
            List<SubTree> subTrees = new ArrayList<>();
            for (Map<String, String> stringStringMap : child) {
                SubTree subTree1 = new SubTree();
                subTree1.setLabel(stringStringMap.get("custom_name"));
                subTree1.setValue(stringStringMap.get("custom_name"));
                subTree1.setChildren(null);
                subTrees.add(subTree1);
            }
            subTree.setChildren(subTrees);
            list.add(subTree);
        }
        return success(list);
    }

    /**
     * 导出记账凭证列表
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:export')")
    @Log(title = "记账凭证", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AccVou accVou) {
        List<AccVou> list = accVouService.selectAccVouList(accVou);
        ExcelUtil<AccVou> util = new ExcelUtil<AccVou>(AccVou.class);
        util.exportExcel(response, list, "记账凭证数据");
    }

    /**
     * 获取记账凭证详细信息
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(accVouService.selectAccVouById(id));
    }

    /**
     * 新增记账凭证
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:add')")
    @Log(title = "记账凭证", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AccVou accVou) {
        return toAjax(accVouService.insertAccVou(accVou));
    }

    /**
     * 修改记账凭证
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:edit')")
    @Log(title = "记账凭证", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AccVou accVou) {
        return toAjax(accVouService.updateAccVou(accVou));
    }

    /**
     * 删除记账凭证
     */
//    @PreAuthorize("@ss.hasPermi('cost:vou:remove')")
    @Log(title = "记账凭证", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(accVouService.deleteAccVouByIds(ids));
    }
}
